Add gdk_drag_context_get_drag_window
authorMatthias Clasen <mclasen@redhat.com>
Wed, 2 Dec 2015 04:33:53 +0000 (23:33 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Wed, 2 Dec 2015 04:47:56 +0000 (23:47 -0500)
This makes gdk_wayland_drag_context_get_dnd_window
backend-independent API and adds an implementation
for X11.

docs/reference/gdk/gdk3-sections.txt
gdk/gdkdnd.c
gdk/gdkdnd.h
gdk/gdkdndprivate.h
gdk/wayland/gdkdnd-wayland.c
gdk/x11/gdkdnd-x11.c

index 8309d1d9777ac25fed41ac8d35b962a9e7d4bf2a..b26ede0ae23c41e8b820bc20c4e8eed8152b5e27 100644 (file)
@@ -967,6 +967,7 @@ gdk_drag_context_set_device
 gdk_drag_context_get_source_window
 gdk_drag_context_get_dest_window
 gdk_drag_context_get_protocol
+gdk_drag_context_get_drag_window
 
 <SUBSECTION Standard>
 GDK_DRAG_CONTEXT
index 2957fe2663e08f680287757cee62788761ed03b7..691b52bff5f7892bad85dedbe2b7480d39bbb87e 100644 (file)
@@ -454,3 +454,29 @@ gdk_drag_get_selection (GdkDragContext *context)
 
   return GDK_DRAG_CONTEXT_GET_CLASS (context)->get_selection (context);
 }
+
+/**
+ * gdk_drag_context_get_drag_window:
+ * @context: a #GdkDragContext
+ *
+ * Returns the window on which the drag icon should be rendered
+ * during the drag operation. Note that the window may not be
+ * available until the drag operation has begun. GDK will move
+ * the window in accordance with the ongoing drag operation.
+ * The window is owned by @context and will be destroyed when
+ * the drag operation is over.
+ *
+ * Returns: (transfer none): the drag window, or %NULL
+ *
+ * Since: 3.20
+ */
+GdkWindow *
+gdk_drag_context_get_drag_window (GdkDragContext *context)
+{
+  g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
+
+  if (GDK_DRAG_CONTEXT_GET_CLASS (context)->get_drag_window)
+    return GDK_DRAG_CONTEXT_GET_CLASS (context)->get_drag_window (context);
+
+  return NULL;
+}
index 8871b2a6b8e781c9c74fef2f74323773f8407823..4d2cd65a7d8111baf38cb3636e35895e40f7f2df 100644 (file)
@@ -171,6 +171,9 @@ void            gdk_drag_abort       (GdkDragContext *context,
 GDK_AVAILABLE_IN_ALL
 gboolean        gdk_drag_drop_succeeded (GdkDragContext *context);
 
+GDK_AVAILABLE_IN_3_20
+GdkWindow      *gdk_drag_context_get_drag_window (GdkDragContext *context);
+
 G_END_DECLS
 
 #endif /* __GDK_DND_H__ */
index 90c3a20d4ad010f1e7dacd94ca107591927f0840..be1626fcbd53508583dc180cb340e9852a6a7a36 100644 (file)
@@ -62,6 +62,7 @@ struct _GdkDragContextClass {
                                 gboolean         success,
                                 guint32          time_);
   gboolean    (*drop_status)   (GdkDragContext  *context);
+  GdkWindow*  (*get_drag_window) (GdkDragContext *context);
 };
 
 struct _GdkDragContext {
@@ -73,6 +74,7 @@ struct _GdkDragContext {
   gboolean is_source;
   GdkWindow *source_window;
   GdkWindow *dest_window;
+  GdkWindow *drag_window;
 
   GList *targets;
   GdkDragAction actions;
index 70956868aa0d0a9962176dee48b247e265566148..7a07078bd5bdabda0707fcdba6069cbeecfd684a 100644 (file)
@@ -293,6 +293,12 @@ gdk_wayland_drag_context_init (GdkWaylandDragContext *context_wayland)
   context->actions = GDK_ACTION_COPY | GDK_ACTION_MOVE;
 }
 
+static GdkWindow *
+gdk_wayland_drag_context_get_drag_window (GdkDragContext *context)
+{
+  return GDK_WAYLAND_DRAG_CONTEXT (context)->dnd_window;
+}
+
 static void
 gdk_wayland_drag_context_class_init (GdkWaylandDragContextClass *klass)
 {
@@ -310,6 +316,7 @@ gdk_wayland_drag_context_class_init (GdkWaylandDragContextClass *klass)
   context_class->drop_finish = gdk_wayland_drag_context_drop_finish;
   context_class->drop_status = gdk_wayland_drag_context_drop_status;
   context_class->get_selection = gdk_wayland_drag_context_get_selection;
+  context_class->get_drag_window = gdk_wayland_drag_context_get_drag_window;
 }
 
 GdkDragProtocol
index e38e1f35fb023889001f563cc2b69721bc209c84..4c818301d30bcb4b9048b18e4a016392022d9bf1 100644 (file)
@@ -85,6 +85,8 @@ struct _GdkX11DragContext
 
   GSList *window_caches;
 
+  GdkWindow *drag_window;
+
   Window dest_xid;             /* The last window we looked up */
   Window drop_xid;             /* The (non-proxied) window that is receiving drops */
   guint xdnd_targets_set  : 1; /* Whether we've already set XdndTypeList */
@@ -183,6 +185,12 @@ static void        gdk_x11_drag_context_drop_finish (GdkDragContext  *context,
 static gboolean    gdk_x11_drag_context_drop_status (GdkDragContext  *context);
 static GdkAtom     gdk_x11_drag_context_get_selection (GdkDragContext  *context);
 
+static GdkWindow *
+gdk_x11_drag_context_get_drag_window (GdkDragContext *context)
+{
+  return GDK_X11_DRAG_CONTEXT (context)->drag_window;
+}
+
 static void
 gdk_x11_drag_context_class_init (GdkX11DragContextClass *klass)
 {
@@ -200,6 +208,7 @@ gdk_x11_drag_context_class_init (GdkX11DragContextClass *klass)
   context_class->drop_finish = gdk_x11_drag_context_drop_finish;
   context_class->drop_status = gdk_x11_drag_context_drop_status;
   context_class->get_selection = gdk_x11_drag_context_get_selection;
+  context_class->get_drag_window = gdk_x11_drag_context_get_drag_window;
 }
 
 static void
@@ -1914,6 +1923,26 @@ gdk_drag_do_leave (GdkX11DragContext *context_x11,
     }
 }
 
+static GdkWindow *
+create_drag_window (GdkScreen *screen)
+{
+  GdkWindowAttr attrs;
+  guint mask;
+
+  attrs.x = attrs.y = 0;
+  attrs.width = attrs.height = 100;
+  attrs.wclass = GDK_INPUT_OUTPUT;
+  attrs.window_type = GDK_WINDOW_TEMP;
+  attrs.type_hint = GDK_WINDOW_TYPE_HINT_DND;
+  attrs.visual = gdk_screen_get_rgba_visual (screen);
+  if (!attrs.visual)
+    attrs.visual = gdk_screen_get_system_visual (screen);
+
+  mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_TYPE_HINT;
+
+  return gdk_window_new (gdk_screen_get_root_window (screen), &attrs, mask);
+}
+
 GdkDragContext *
 _gdk_x11_window_drag_begin (GdkWindow *window,
                             GdkDevice *device,
@@ -1934,6 +1963,8 @@ _gdk_x11_window_drag_begin (GdkWindow *window,
 
   gdk_drag_context_set_device (context, device);
 
+  GDK_X11_DRAG_CONTEXT (context)->drag_window = create_drag_window (gdk_window_get_screen (window));
+
   return context;
 }
 
@@ -2088,6 +2119,12 @@ gdk_x11_drag_context_drag_motion (GdkDragContext *context,
   GdkX11DragContext *context_x11 = GDK_X11_DRAG_CONTEXT (context);
   GdkWindowImplX11 *impl;
 
+  if (context_x11->drag_window)
+    {
+      gdk_window_move (context_x11->drag_window, x_root, y_root);
+      gdk_window_raise (context_x11->drag_window);
+    }
+
   context_x11->old_actions = context->actions;
   context->actions = possible_actions;